import axios from 'axios'
import store from '@/store/index.js'
// 导入接口大数据处理
import JsonBigint from 'json-bigint'
import router from '@/router'
import { reqRefreshNewToken } from '@/api/user.js'

// http => 携带着自定义配置axios
// http用法和axios完全一样  request({url:''})
const http = axios.create({
  baseURL: 'http://toutiao.itheima.net',
  timeout: 5000,
  // transformResponse 这个节点是转换响应的数据,如果配置这一项,axios不会处理响应的数据,
  // 需要我们手动处理
  transformResponse: [function (data) {
    try {
      return JsonBigint.parse(data)
    } catch (e) {
      // 解析不了的数据，说明不是json格式，直接输出
      return data
    }
  }]
})

// 添加请求拦截器
http.interceptors.request.use(function (config) {
    // 在发送请求之前,先获取token,将token存放在请求头
    // 这是后端接口要求的，实际项目情况，可以根据后端的设计做出相应的调整
    const token = store.state.user.tokenInfo.token
    if (token && !config.headers.Authorization) {
      // 请求头挂载token
      config.headers.Authorization = `Bearer ${token}`
    }

    return config
  }, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error)
  }
)

// 添加响应拦截器
http.interceptors.response.use(
  function (response) {
    // 经过这个函数，就是成功的响应 response  res
    // 响应给客户端的数据,是一个对象
    return response
  }, async function (error) {
    // 经过这个函数，就是失败的响应
    // 401：用户未认证
    if (error.response.status === 401) {
      // token过期了，需要通过refresh_token,重新去刷新token
      const refreshToken = store.state.user.tokenInfo.refresh_token
      // 判断是否存在
      if (refreshToken) {
        try {
          console.log('刷新一份新的token')
          // 1.调用接口，刷新token
          const res = await reqRefreshNewToken()
          // 2.将新的token存储到vuex和本地localStorage中
          store.commit('user/setTokenInfo', {
            refresh_token: refreshToken,
            token: res.data.data.token
          })
          // 3.重新使用我们创建的http实例, 再次发送请求
          // 将失败请求的携带的token更新成返回的新token才可以
          error.config.headers.Authorization = `Bearer ${token}` // 这一行不加， 会一直刷新token

          // 4.重新使用我们创建的http实例, 在error错误信息对象中,有一个config,
          // 这个config就是之前请求失败的请求,只需要重新发送这个请求即可
          return http(error.config)
        } catch (e) {
          // 万一refresh_token也过期了，就需要用户重新登录了
          console.log('refresh_token过期，重新登录')
          // 重新登录，并且携带之前访问的路由信息，登录成功后原路返回
          // 1.触发vuex中清除tokenInfo的mutation
          store.commit('user/removeTokenInfo')
          router.push({
            path: '/login',
            query: {
              // 携带当前路由信息的fullPath  currentRoute标识当前路由信息对象 this.$route
              backto: router.currentRoute.fullPath
            }
          })
        }

        // 不存在
      } else {
        console.log('refresh_token不存在，重新登录')
        // 重新登录，并且携带之前访问的路由信息，登录成功后原路返回
        // 1.触发vuex中清除tokenInfo的mutation
        store.commit('user/removeTokenInfo')
        router.push({
          path: '/login',
          query: {
            // 携带当前路由信息的fullPath  currentRoute标识当前路由信息对象 this.$route
            backto: router.currentRoute.fullPath
          }
        })
      }
    }

    return Promise.reject(error)
  }
)

// axios请求 返回的数据结构 => {data:{data:[],code:200}}
export default http
